#include "header.h"
#include <new>
#include <iostream>
#include <fstream>
#include <iomanip>

unsigned entity::getId() {
	return _id;
}
entity::entity(linkTab *d, unsigned id) {
	_id=id;
	data=d;
}
entity::entity() {
	_id=0xFFFF;
	data=NULL;
}
double& entity::enqueue() {
	return data->enqueue;
}
double& entity::enserver() {
	return data->enserver;
}
double& entity::deserver() {
	return data->deserver;
}
int& entity::serverId() {
	return data->serverId;
}
int& entity::queueId() {
	return data->queueId;
}
bool& entity::balk() {
	return data->balk;
}
PopulationMgr::PopulationMgr() {
	count=0;
	tab=NULL;
	report=false;
	file=false;
}
PopulationMgr::~PopulationMgr() {
	linkTab *ptr;
	std::ofstream ofs("out.csv");
	if (!ofs) {
		throw FILEERROR_CANNOTOPEN;
	}
	if (report) {
		std::cout << "=============Entity Statistics===========" << std::endl;
		std::cout << std::setiosflags(std::ios::showpoint);
	}
	while (tab != NULL) {
		count--;
		if (report) {
			std::cout << "Entity " << count << ":" << std::endl;
			std::cout << "\tenqueue ="<< (tab->enqueue) <<"\tqueue =" << (tab->queueId) << std::endl;
			if (tab->balk) {
				std::cout << "\tBalk" << std::endl;
			}
			else {
				std::cout << "\tenserver="<< (tab->enserver) <<"\tserver=" << (tab->serverId) << std::endl;
				std::cout << "\tdeserver=" << (tab->deserver) << std::endl;
			}
		}
		if (file) {
			ofs << count << ',' << (tab->queueId) << ',' << (tab->enqueue);
			if (tab->balk) {
				ofs << ',' << -1 << ',' << 0 << ',' << 0 << '\n';
			}
			else {
				ofs << ',' << (tab->serverId) << ',' << (tab->enserver) << ',' << (tab->deserver) <<','<< (tab->deserver - tab->enqueue) << ','<< (tab->enserver - tab->enqueue)<<'\n';
			}
		}
		ptr=tab;
		tab=tab->next;
		try {
			delete ptr;
		}
		catch (...) {
			throw MEMERROR_FREE;
		}
	}
}
unsigned PopulationMgr::getCount() {
	return count;
}
entity PopulationMgr::getEntity(unsigned id) {
	linkTab *ptr = NULL;
	unsigned i;

	if (id >= count ) {
		throw LOGICERROR_INVAILDID;
	}
	ptr = tab;
	if (ptr == NULL) {
		throw LOGICERROR_LINKTAB;
	}
	for (i=count; i != id+1; i--) {
		ptr=ptr->next;
		if (ptr == NULL) {
			throw LOGICERROR_LINKTAB;
		}
	}

	entity r(ptr,id);
	return r;
}
entity PopulationMgr::newEntity() {
	linkTab *ptr = NULL;
	ptr = tab;
	
	try {
		tab=new linkTab;
	}
	catch (std::bad_alloc &e) {
		throw MEMERROR_ALLOC;
	}
	if ( tab==NULL ) {
		throw MEMERROR_ALLOC;
	}

	tab->next=ptr;
	tab->enqueue=0;
	tab->enserver=0;
	tab->deserver=0;
	tab->queueId=0;
	tab->serverId=0;
	tab->balk=false;
	count++;
	entity r(tab,count-1);
	return r;
}
unsigned PopulationMgr::balkCount() {
	unsigned i=0;
	linkTab *ptr = NULL;
	ptr = tab;
	for (i = 0; ptr != NULL; ptr = ptr->next) {
		if ( ptr->balk ) {
			i++;
		}
	}
	return i;
}
